import pandas as pd
import numpy as np
import pandas as pd
from keras.models import load_model
from keras import backend as K


def precision(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    return true_positives / (predicted_positives + K.epsilon())


def recall(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    return true_positives / (possible_positives + K.epsilon())


def f1(y_true, y_pred):
    def precision(y_true, y_pred):
        true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
        predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
        precision = true_positives / (predicted_positives + K.epsilon())
        return precision

    def recall(y_true, y_pred):
        true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
        possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
        recall = true_positives / (possible_positives + K.epsilon())
        return recall

    precision = precision(y_true, y_pred)
    recall = recall(y_true, y_pred)
    return 2 * ((precision * recall) / (precision + recall + K.epsilon()))


def tversky_loss(y_true, y_pred):
    # 这俩参数能调，aplha是多惩罚假阳性，beta是多惩罚假阴性

    alpha = 0.5

    beta = 1 - alpha

    ones = K.ones(K.shape(y_true))

    p0 = y_pred  # proba that voxels are class i

    p1 = ones - y_pred  # proba that voxels are not class i

    g0 = y_true

    g1 = ones - y_true

    num = K.sum(p0 * g0)

    den = num + alpha * K.sum(p0 * g1) + beta * K.sum(p1 * g0)

    T = K.sum(num / den)  # when summing over classes, T has dynamic range [0 Ncl]

    Ncl = K.cast(K.shape(y_true)[-1], 'float32')

    return Ncl - T
def save_csv(num):

    df_original=pd.read_csv("train_original.csv")
    area={i:j for i,j in zip(list(set(df_original["area_id"])),range(0,len(list(set(df_original["area_id"]))),1))}
    df=pd.read_csv("test.csv")
    data=pd.DataFrame(df,columns=['user_id','prov_id', 'area_id',  'chnl_type', 'service_type', 'product_type', 'innet_months', 'total_times', 'total_flux', 'total_fee', 'pay_fee', 'sex', 'age', 'manu_name', 'term_type', 'max_rat_flag', 'is_5g_base_cover', 'is_work_5g_cover', 'is_home_5g_cover', 'is_work_5g_cover_l01', 'is_home_5g_cover_l01', 'is_work_5g_cover_l02', 'is_home_5g_cover_l02', 'activity_type', 'is_act_expire', 'comp_type', 'call_days', 're_call10', 'short_call10', 'long_call10', 'bank_cnt', 'active_days01', 'active_days02', 'active_days03', 'active_days04', 'active_days05', 'active_days06', 'active_days07', 'active_days08', 'active_days09', 'active_days10', 'active_days11', 'active_days12', 'active_days13', 'active_days14', 'active_days15', 'active_days16', 'active_days17', 'active_days18', 'active_days19', 'active_days20', 'active_days21', 'active_days22', 'active_days23', 'game_app_flux', 'live_app_flux', 'video_app_flux', 'city_5g_ratio', 'city_level'])
    df_total=pd.DataFrame(df_original,columns=['user_id','prov_id', 'area_id',  'chnl_type', 'service_type', 'product_type', 'innet_months', 'total_times', 'total_flux', 'total_fee', 'pay_fee', 'sex', 'age', 'manu_name', 'term_type', 'max_rat_flag', 'is_5g_base_cover', 'is_work_5g_cover', 'is_home_5g_cover', 'is_work_5g_cover_l01', 'is_home_5g_cover_l01', 'is_work_5g_cover_l02', 'is_home_5g_cover_l02', 'activity_type', 'is_act_expire', 'comp_type', 'call_days', 're_call10', 'short_call10', 'long_call10', 'bank_cnt', 'active_days01', 'active_days02', 'active_days03', 'active_days04', 'active_days05', 'active_days06', 'active_days07', 'active_days08', 'active_days09', 'active_days10', 'active_days11', 'active_days12', 'active_days13', 'active_days14', 'active_days15', 'active_days16', 'active_days17', 'active_days18', 'active_days19', 'active_days20', 'active_days21', 'active_days22', 'active_days23', 'game_app_flux', 'live_app_flux', 'video_app_flux', 'city_5g_ratio', 'city_level'])

    app=data.loc[:,"active_days01":'active_days23']
    app["app_sum"]=app.sum(axis=1)
    data=data.drop(['active_days01', 'active_days02', 'active_days03', 'active_days04', 'active_days05', 'active_days06', 'active_days07', 'active_days08', 'active_days09', 'active_days10', 'active_days11', 'active_days12', 'active_days13', 'active_days14', 'active_days15', 'active_days16', 'active_days17', 'active_days18', 'active_days19', 'active_days20', 'active_days21', 'active_days22', 'active_days23'],axis=1)
    data["app_sum"]=app["app_sum"]

    app_total=df_total.loc[:,"active_days01":'active_days23']
    app_total["app_sum"]=app_total.sum(axis=1)
    df_total=df_total.drop(['active_days01', 'active_days02', 'active_days03', 'active_days04', 'active_days05', 'active_days06', 'active_days07', 'active_days08', 'active_days09', 'active_days10', 'active_days11', 'active_days12', 'active_days13', 'active_days14', 'active_days15', 'active_days16', 'active_days17', 'active_days18', 'active_days19', 'active_days20', 'active_days21', 'active_days22', 'active_days23'],axis=1)
    df_total["app_sum"]=app_total["app_sum"]
    def handle_area(x):
        return area[x]
    data['area_id']=data['area_id'].apply(handle_area)
    df_total['area_id']=df_total['area_id'].apply(handle_area)


    data_train=data.iloc[:,1:]
    data_train=(data_train-df_total.iloc[:,1:].mean())/df_total.iloc[:,1:].std()
    data.iloc[:,1:]=data_train
    keepfour=lambda x: float(round(x,5))
    data.iloc[:,1:]=(data.iloc[:,1:]).applymap(keepfour)
    print([column for column in data])

    data_test=np.array(data[[ 'prov_id', 'area_id', 'chnl_type', 'service_type', 'product_type', 'innet_months', 'total_times', 'total_flux', 'total_fee', 'pay_fee', 'sex', 'age', 'manu_name', 'term_type', 'max_rat_flag', 'is_5g_base_cover', 'is_work_5g_cover', 'is_home_5g_cover', 'is_work_5g_cover_l01', 'is_home_5g_cover_l01', 'is_work_5g_cover_l02', 'is_home_5g_cover_l02', 'activity_type', 'is_act_expire', 'comp_type', 'call_days', 're_call10', 'short_call10', 'long_call10', 'bank_cnt', 'game_app_flux', 'live_app_flux', 'video_app_flux', 'city_5g_ratio', 'city_level', 'app_sum']])
    print(data_test)
    model_1 = load_model("model_1.h5", custom_objects={"f1": f1, "recall": recall, "precision": precision,"tversky_loss":tversky_loss})
    predict_test=model_1.predict(data_test)
    predict_test=np.where(predict_test<=0.5,0,1)
    predict_test=pd.DataFrame(predict_test)
    result=data[["user_id"]].join(predict_test)
    result=result.rename(columns={"user_id":"user_id",0:"is_5g"})
    print(result)
    result.to_csv("F:\emsenble\predict_{}.csv".format(str(num)),index=0)
